#pragma once

#include <vector>
using std::vector;

template< typename T >
class CAdjacencyMatrix
{
private:
	CAdjacencyMatrix() { }

public:
	explicit CAdjacencyMatrix(int row)
		: m_row(row)
		, m_vecData(row*(row-1)/2)
	{ }

	explicit CAdjacencyMatrix(const CAdjacencyMatrix<T>& adjMatrix)
		: m_row(adjMatrix.m_row)
		, m_vecData(adjMatrix.m_vecData.begin(),adjMatrix.m_vecData.end())
	{ }

	CAdjacencyMatrix<T>& operator=(const CAdjacencyMatrix<T>& adjMatrix)
	{
		m_vecData.clear();
		m_row = adjMatrix.m_row;
		m_vecData.assign(adjMatrix.m_vecData.begin(),adjMatrix.m_vecData.end());
		return *this;
	}

	~CAdjacencyMatrix() {}

public:
	typename vector<T>::reference operator()(int row, int col)
	{
		ARX_ASSERT((row>=0) && (col>=0) && (row!=col) 
			&& (row<m_row) && (col<m_row));
		int r = row, c=col;
		if (row<col)
		{
			r = col;
			c = row;
		}
		ARX_ASSERT(r>c);
		return m_vecData[r*(r-1)/2+c];
	}

	typename vector<T>::const_reference operator()(int row, int col) const
	{
		ARX_ASSERT((row>=0) && (col>=0) && (row!=col) 
			&& (row<m_row) && (col<m_row));
		int r = row, c=col;
		if (row<col)
		{
			r = col;
			c = row;
		}
		ARX_ASSERT(r>c);
		return m_vecData[r*(r-1)/2+c];
	}

	bool IsNull(int row, int col) const
	{
		ARX_ASSERT((row>=0) && (col>=0) && (row!=col) 
			&& (row<m_row) && (col<m_row));
		return ( operator()(row,col)==T() );
	}

	void SetNull(int row, int col)
	{
		ARX_ASSERT((row>=0) && (col>=0) && (row!=col) 
			&& (row<m_row) && (col<m_row));
		operator()(row,col) = T();
	}

	void Assign(const T& elemValue)
	{
		m_vecData.assign(m_vecData.size(),elemValue);
	}

private:
	int m_row;
	vector<T> m_vecData;
};